use axum::{
    extract::State,
    Json,
};
use chrono::DateTime;
use tracing::{info, warn, error};
use utoipa::ToSchema;
use crate::error::{AppError, AppResult};
use crate::models::{WeChatMessage, WeChatResponse, CreateChat, CreatePlan};
use crate::routes::AppState;
use crate::services::{AIService, UserService, PlanService, ChatService};

/// 处理提醒业务逻辑
#[utoipa::path(
    post,
    path = "/reminder",
    tag = "reminder",
    request_body = WeChatMessage,
    responses(
        (status = 200, description = "处理成功，返回响应消息", body = WeChatResponse),
        (status = 400, description = "请求无效"),
        (status = 500, description = "服务器内部错误"),
    )
)]
pub async fn handle_reminder(
    State(state): State<AppState>,
    Json(wechat_msg): Json<WeChatMessage>,
) -> AppResult<Json<WeChatResponse>> {
    // 检查消息是否已在处理中
    if state.msg_cache.is_processing(&wechat_msg.msgid) {
        info!("Message {} is already being processed, ignoring duplicate", wechat_msg.msgid);
        return Ok(Json(WeChatResponse::new_text("".to_string())));
    }
    
    // 标记消息为处理中
    state.msg_cache.mark_processing(&wechat_msg.msgid);
    
    // 处理消息
    let response = process_message(&state, wechat_msg.clone()).await;
    
    // 处理完成后从缓存中删除
    state.msg_cache.remove(&wechat_msg.msgid);
    
    Ok(Json(response?))
}

/// 处理微信消息（内部方法，可被 callback 调用）
pub async fn process_message(
    state: &AppState,
    wechat_msg: WeChatMessage,
) -> AppResult<WeChatResponse> {
    info!("Processing message from user: {}", wechat_msg.from.userid);
    
    // 只处理文本消息
    if wechat_msg.msgtype != "text" {
        return Ok(WeChatResponse::new_text("目前只支持文本消息".to_string()));
    }
    
    let user_content = wechat_msg
        .text
        .as_ref()
        .map(|t| t.content.as_str())
        .unwrap_or("");
    
    if user_content.trim().is_empty() {
        return Ok(WeChatResponse::new_text("请输入提醒内容".to_string()));
    }
    
    // 1. 查找或创建用户
    let user = UserService::find_or_create_user(&state.pool, &wechat_msg.from.userid).await?;
    info!("User found/created: id={}, name={}", user.id, user.name);
    
    // 2. 调用 AI 服务生成计划
    let ai_service = AIService::new(state.config.openai_silicoflow.clone());
    let ai_response = ai_service.generate_plan(user_content).await?;
    info!("AI response: {}", ai_response);
    
    // 3. 尝试解析 AI 响应
    let response_text = if let Some(plan_suggestion) = ai_service.parse_plan_suggestion(&ai_response) {
        // AI 返回了完整的计划
        info!("Plan suggestion parsed: {:?}", plan_suggestion);
        
        // 解析提醒时间
        match parse_reminder_time(&plan_suggestion.next_reminder) {
            Ok(next_reminder) => {
                // 创建计划
                let create_plan = CreatePlan {
                    user_id: user.id,
                    name: plan_suggestion.name.clone(),
                    description: plan_suggestion.description.clone(),
                    frequency: plan_suggestion.frequency.clone(),
                    next_reminder,
                };
                
                match PlanService::create_plan(&state.pool, create_plan).await {
                    Ok(plan) => {
                        info!("Plan created: id={}", plan.id);
                        // 生成简洁的确认回复
                        generate_confirmation_message(&plan)
                    }
                    Err(e) => {
                        error!("Failed to create plan: {}", e);
                        format!("创建计划失败: {}", e)
                    }
                }
            }
            Err(e) => {
                warn!("Failed to parse reminder time: {}", e);
                format!("时间格式解析失败: {}，请提供有效的时间", e)
            }
        }
    } else {
        // AI 需要更多信息或返回了询问
        ai_response.clone()
    };
    
    // 4. 保存聊天记录
    let create_chat = CreateChat {
        user_id: user.id,
        user_message: user_content.to_string(),
        ai_message: ai_response.clone(),
    };
    
    if let Err(e) = ChatService::save_chat(&state.pool, create_chat).await {
        error!("Failed to save chat: {}", e);
    }
    
    Ok(WeChatResponse::new_text(response_text))
}

/// 解析提醒时间
/// 支持两种格式:
/// 1. RFC3339 格式带时区: "2025-11-03T15:00:00+08:00"
/// 2. 简单格式: "2025-11-03 15:00:00" (默认为中国时间 UTC+8)
fn parse_reminder_time(time_str: &str) -> AppResult<DateTime<chrono::Utc>> {
    // 尝试解析 ISO 8601 格式
    DateTime::parse_from_rfc3339(time_str)
        .map(|dt| dt.with_timezone(&chrono::Utc))
        .or_else(|_| {
            // 尝试解析其他格式，并假设为中国时间 (UTC+8)
            chrono::NaiveDateTime::parse_from_str(time_str, "%Y-%m-%d %H:%M:%S")
                .map(|ndt| {
                    // 将中国时间转为 UTC 时间 (减去 8 小时)
                    let utc_ndt = ndt - chrono::Duration::hours(8);
                    DateTime::<chrono::Utc>::from_naive_utc_and_offset(utc_ndt, chrono::Utc)
                })
        })
        .map_err(|e| AppError::ParseError(format!("Invalid datetime format: {}", e)))
}

/// 格式化频率显示
fn format_frequency(frequency: &str) -> &str {
    match frequency {
        "daily" => "每天",
        "weekly" => "每周",
        "monthly" => "每月",
        "yearly" => "每年",
        "once" => "仅一次",
        _ => "未知",
    }
}

/// 生成简洁的确认消息
fn generate_confirmation_message(plan: &crate::models::Plan) -> String {
    use chrono::{Timelike, Datelike};
    use rand::Rng;
    
    // 格式化时间（更友好的显示）
    let local_time = plan.next_reminder + chrono::Duration::hours(8); // 转为中国时间显示
    let time_str = if local_time.date_naive() == chrono::Local::now().date_naive() {
        // 今天
        format!("今天 {}:{:02}", local_time.hour(), local_time.minute())
    } else if local_time.date_naive() == (chrono::Local::now() + chrono::Duration::days(1)).date_naive() {
        // 明天
        format!("明天 {}:{:02}", local_time.hour(), local_time.minute())
    } else {
        // 其他日期
        format!(
            "{}月{}日 {}:{:02}",
            local_time.month(),
            local_time.day(),
            local_time.hour(),
            local_time.minute()
        )
    };
    
    // 频率描述
    let freq_str = match plan.frequency.as_str() {
        "daily" => "，之后每天重复",
        "weekly" => "，之后每周重复",
        "monthly" => "，之后每月重复",
        "yearly" => "，之后每年重复",
        _ => "",
    };
    
    // 随机选择一个确认语句（增加趣味性）
    let mut rng = rand::thread_rng();
    let confirmations = [
        "好的，记下来了！",
        "明白啦！",
        "收到！",
        "好嘞！",
        "没问题！",
        "OK，交给我吧！",
    ];
    let confirmation = confirmations[rng.gen_range(0..confirmations.len())];
    
    format!("{} 我会在{}提醒你{} 😊", confirmation, time_str, freq_str)
}
